import axios from 'axios';
import * as THREE from 'three';
import { Tween, Easing } from '@tweenjs/tween.js';

const textureLoader = new THREE.TextureLoader();

export class cccc {
  color = '#000';
  tween: any;
  mesh = new THREE.Group();
  coneMaterial: THREE.MeshBasicMaterial;
  hexagonMaterial: THREE.MeshBasicMaterial;
  constructor(color) {
    this.color = color;
    this.coneMaterial = new THREE.MeshBasicMaterial({
      vertexColors: true
    });
    this.hexagonMaterial = new THREE.MeshBasicMaterial({
      color: new THREE.Color(this.color).addScalar(0.1),
      alphaMap: textureLoader.load('images/dot.png'),
      transparent: true,
      blending: THREE.AdditiveBlending,
      side: THREE.BackSide,
      depthTest: false
    });
    this.loadData();
  }
  async loadData() {
    let group = new THREE.Group();
    let group2 = new THREE.Group();
    var res = await axios.get('data/gdp.json').then(r => r.data);
    var res2 = await axios.get('data/city_gs_data.json').then(r => r.data);
    var gdpdata = this.getCountryGdpColor(res);
    for (const key in gdpdata) {
      if (res2[key]) {
        const height = gdpdata[key].value;
        const position = this.createPosition(res2[key]);
        if (height <= 1) {
          group.add(this.createHexagon(position, 25)); // 地标
        } else {
          group2.add(this.createCone(position, height)); // 光锥
        }
      }
    }
    group2.children.forEach((mesh: any) => {
      mesh.scale.set(0, 0, 0);
    });
    this.mesh.add(group, group2);
    this.animate();
  }
  animate() {
    this.tween = new Tween([0]).to([1], 5000);
    this.tween.easing(Easing.Quadratic.InOut);
    this.tween.onUpdate(e => {
      this.mesh.children[1].children.forEach(mesh => {
        mesh.scale.set(e[0], e[0], e[0]);
      });
    });
    this.tween.onComplete(() => {
      this.tween = null;
    });
    this.tween.start();
  }
  update() {
    if (this.tween) {
      this.tween.update();
    }
  }
  setColor(color) {
    this.color = color;
    let arr: THREE.Mesh[] = [];
    if (this.mesh?.children[1]?.children) {
      arr = this.mesh?.children[1]?.children as THREE.Mesh[];
    }
    arr.forEach(mesh => {
      var colorArr: any[] = [];
      var color1 = new THREE.Color(color);
      var color2 = color1.clone().addScalar(0.2);
      // 由于 mesh 可能不是 Mesh 类型，需要进行类型断言
      var pos = mesh.geometry.attributes.position;
      for (var i = 0; i < pos.count; i++) {
        if (pos.getZ(i) < 1) {
          colorArr.push(color1.r, color1.g, color1.b);
        } else {
          colorArr.push(color2.r, color2.g, color2.b);
        }
      }
      mesh.geometry.attributes.color = new THREE.BufferAttribute(new Float32Array(colorArr), 3);
    });
  }
  createHexagon(position, size) {
    let hexagonPlane = new THREE.PlaneGeometry(size, size);
    let circlePlane = new THREE.Mesh(hexagonPlane, this.hexagonMaterial);
    circlePlane.position.copy(position);
    circlePlane.lookAt(new THREE.Vector3(0, 0, 0));
    return circlePlane;
  }

  createCone(position, height) {
    var colorArr: any[] = [];
    var color1: any = new THREE.Color(this.color);
    var color2: any = color1.clone().addScalar(0.2);
    var geometry = new THREE.BoxGeometry(5, 5, height);
    var pos = geometry.attributes.position;
    for (var i = 0; i < pos.count; i++) {
      if (pos.getZ(i) < 1) {
        colorArr.push(color1.r, color1.g, color1.b);
      } else {
        colorArr.push(color2.r, color2.g, color2.b);
      }
    }
    geometry.attributes.color = new THREE.BufferAttribute(new Float32Array(colorArr), 3);
    geometry.translate(0, 0, 1000 + height / 2);
    geometry.lookAt(new THREE.Vector3(position.x, position.y, position.z));
    return new THREE.Mesh(geometry, this.coneMaterial);
  }
  createPosition(lnglat) {
    let spherical = new THREE.Spherical();
    spherical.radius = 1000;
    const lng = lnglat[0];
    const lat = lnglat[1];
    const theta = (lng + 90) * (Math.PI / 180);
    const phi = (90 - lat) * (Math.PI / 180);
    spherical.phi = phi;
    spherical.theta = theta;
    let position = new THREE.Vector3();
    position.setFromSpherical(spherical);
    return position;
  }
  getCountryGdpColor(data) {
    // data.Root.data.record //所有国家相关的数据
    // 所有国家的数据没有集中放在一起，data.Root.data.record的一个元素是一个对象，包含国家名称、gdp数据、对应年份
    var countryGdpColor = {}; //每个国家的名字作为属性，属性值是国家对应GDP和可视化颜色值
    var color1 = new THREE.Color(0xccff00);
    var color2 = new THREE.Color(0xffffff); //最大数值对应柱子颜色
    var gdpMax = 18219297584000; //设置一个基准值,以最高的美国gdp为准
    data.forEach(function (obj) {
      if (obj.field[2].text == 2018) {
        //获取所有国家2018gdp等数据
        var name = obj.field[0].text; //国家名称
        var gdp = obj.field[3].text; //2015年该国家gdp
        var color: any = null;
        if (gdp) {
          // 部分国家2015数据残缺，意味着gdp未定义
          // 颜色插值计算
          // var color = color1.clone().lerp(color2.clone(), gdp / gdpMax);
          // 国家gdp差距太大，可以使用平方根比值进行颜色插值
          color = color1.clone().lerp(color2.clone(), Math.sqrt(gdp / gdpMax));
        } else {
          color = new THREE.Color(0xffffff);
        }
        //国家名字作为对象属性名
        var value = gdp * 0.0000000001;
        value = value < 1 ? 1 : value;
        countryGdpColor[name] = { value, color };
      }
    });

    return countryGdpColor;
  }
}

export default class {
  mesh = new THREE.Group();
  constructor() {
    const xx = new THREE.BoxGeometry(100, 100, 10000);
  }
  setColor(color) {}
  update() {}
}
